﻿// ------------------------------------------------------------------------
//  Copyright 2025 The Dapr Authors
//  Licensed under the Apache License, Version 2.0 (the "License");
//  you may not use this file except in compliance with the License.
//  You may obtain a copy of the License at
//      http://www.apache.org/licenses/LICENSE-2.0
//  Unless required by applicable law or agreed to in writing, software
//  distributed under the License is distributed on an "AS IS" BASIS,
//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//  See the License for the specific language governing permissions and
//  limitations under the License.
//  ------------------------------------------------------------------------

using System.Diagnostics.CodeAnalysis;
using Dapr.DistributedLock.Models;
using Autogenerated = Dapr.Client.Autogen.Grpc.v1;

namespace Dapr.DistributedLock;

/// <summary>
/// A client for performing distributed locking operations with Dapr.
/// </summary>
[Experimental("DAPR_DISTRIBUTEDLOCK", UrlFormat = "https://docs.dapr.io/developing-applications/building-blocks/distributed-lock/distributed-lock-api-overview/")]
public abstract class DaprDistributedLockClient : IDaprDistributedLockClient
{
    private bool disposed;
    private readonly Autogenerated.Dapr.DaprClient client;
    private readonly string daprApiToken;

    /// <summary>
    /// A client for performing distributed locking operations with Dapr.
    /// </summary>
    protected DaprDistributedLockClient(Autogenerated.Dapr.DaprClient client, HttpClient _, string daprApiToken)
    {
        this.client = client;
        this.daprApiToken = daprApiToken;
    }

    internal Autogenerated.Dapr.DaprClient Client => client;
    internal string DaprApiToken => daprApiToken;

    /// <inheritdoc />
    public abstract Task<LockResponse?> TryLockAsync(string storeName, string resourceId, string lockOwner,
        int expiryInSeconds,
        CancellationToken cancellationToken = default);

    /// <inheritdoc />
    public abstract Task<UnlockResponse> TryUnlockAsync(string storeName, string resourceId, string lockOwner,
        CancellationToken cancellationToken = default);
    
    /// <inheritdoc />
    public void Dispose()
    {
        if (!this.disposed)
        {
            Dispose(disposing: true);
            this.disposed = true;
        }
    }

    /// <summary>
    /// Disposes the resources associcated with the object.
    /// </summary>
    /// <param name="disposing"><c>true</c> if called by a call to the <c>Dispose</c> method; otherwise false.</param>
    protected virtual void Dispose(bool disposing)
    {
    }
}
